#include "connection_manager.h"

using namespace NetKit;

ConnectionManager::ConnectionManager() 
{
	m_iUsed = 0;
	m_iMaxFd = 1024;
	//m_ppConns = (Connection**)(malloc)(sizeof(Connection*)*(m_iMaxFd+1));
	m_pConnItem = new ConnectionItem[m_iMaxFd+1];
	for ( uint32_t i=0; i<(m_iMaxFd+1); ++i )
	{
		//m_ppConns[i] = NULL;
		Connection* pConn = new Connection();
		m_lstIdleConn.push_back(pConn);
	}
}

ConnectionManager::~ConnectionManager()
{	
	std::list<Connection*>::iterator iter = m_lstIdleConn.begin();
	for ( iter = m_lstIdleConn.begin(); iter != m_lstIdleConn.end(); ++iter)
	{
		delete *iter;
	}
	m_lstIdleConn.clear();
	
	for ( uint32_t i=0; i<m_iMaxFd+1; ++i )
	{
		if ( m_pConnItem[i].conn != NULL )
		{
			delete m_pConnItem[i].conn;
			m_pConnItem[i].conn = NULL;
		}
	}
	delete[] m_pConnItem;
}

void ConnectionManager::AddConnection(Processor* pProcessor, TcpSocket* pSock)
{
	Connection* pConn;
	if ( m_lstIdleConn.size() >= 1 )
	{
    	pConn = m_lstIdleConn.back();
		m_lstIdleConn.pop_back();
		pConn->SetTcpSocket(pSock);
		pConn->SetProcessor(pProcessor);
	}
	else
	{
		pConn = new Connection(pProcessor, pSock);
	}
	
	if ( pSock->GetFd() > m_iMaxFd )
	{
		Grow(pSock->GetFd());
	}
	
	AddConnection(pSock->GetFd(), pConn, NETWORK_EVENT);
}

void ConnectionManager::AddConnection(int fd, Connection* pConn, EVENT_TYPE event_type)
{
	m_pConnItem[fd].conn = pConn;
	m_pConnItem[fd].event_type = event_type;
	++m_iUsed;	
}

void ConnectionManager::RemoveConnection(Connection* pConn)
{
	if ( pConn->GetSocketPairFd() != -1 )
	{
		//cout << "remove socket pair connection:" << pConn->GetSocketPairFd()  << endl;
		m_pConnItem[pConn->GetSocketPairFd()].conn = NULL;
	}
	
	m_pConnItem[pConn->GetFd()].conn =  NULL;
	pConn->Close();
	m_lstIdleConn.push_back(pConn);
}

void ConnectionManager::RemoveConnection(int sock_pair_fd, Connection* pConn)
{
	m_pConnItem[sock_pair_fd].conn =  NULL;
}

ConnectionItem* ConnectionManager::GetConnectionItem(int fd)
{
	return &m_pConnItem[fd];
}

void ConnectionManager::Grow(int maxFd)
{
	ConnectionItem* pNew = new ConnectionItem[maxFd+1];
	uint32_t i = 0;
	for ( ; i<m_iMaxFd+1; ++i )
	{
		pNew[i] = m_pConnItem[i];
	}
	delete[] m_pConnItem;
	m_pConnItem = pNew;
	m_iMaxFd = maxFd;
}
